<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>let var const</title>
</head>
<body>
<script>
    // js严格模式
    // 'use strict'

    // let b = 10;
    // const c = 10;
// 1.是否存在变量提升？
// 2.是否存在暂时性死区？
// 3.是否允许重复声明变量？
// 4.是否存在块级作用域？
// 5.是否能修改声明的变量？

    //变量提升:变量在声明之前可以使用,并且代码不报错 (预解释 预解析
    //1.用var声明的变量 存在变量提升
    //2.用let和const声明的变量 不存在变量提升

    // console.log(a);//undefined
    // var a = 10;
    //
    // var fn = function (){};
    // fn();
    // function fn(){
    //
    // }

    // console.log(a);
    //Cannot access 'a' before initialization
    //a初始化 之前不可以使用
    // let a = 10;
    // const a = 10;



    //是否允许重复声明变量
    //1.用var声明的变量 允许重复声明
    //2.用let和const声明的变量 不允许重复声明
    var a = 123;
    var a = 456;
    let b = [];
    // let b = {}; //Identifier 'b' has already been declared
    //               b在声明之前已经被使用过了,不允许重复声明
    console.log(a);//{}
    console.log(b);//{}


    //是否存在块级作用域
    //作用域 全局作用域 局部作用域(函数作用域) 块级作用域
    //1.用var声明的变量 不存在块级作用域
    //2.用let和const声明的变量 存在块级作用域
    // var global = [];
    //
    // function fn(){
    //     var global = {};
    // }
    // console.log(global) //[]

    // {} //在ES6中一个{}就可以表示为一个块级作用域
    //ES5中
    // var global = 1;
    // if(global === 1){
    //     var global = 2;
    // }
    // console.log(global)

    let global = 1;
    if(global === 1){
        // console.log("global块级作用域",global)
        let global = 2;
    }
    console.log("global全局作用域",global)


    {
        let temp = 1;
        {
            let temp = 1;
            {
                let temp = 1;
            }
        }
    }


    //是否存在暂时性死区
    //在用let声明一个变量之前 都不能使用这个变量,否则就会报错, 在这之前的代码块,对于这个变量来说都叫暂时性死区
    //1.用var声明的变量 不存在暂时性死区
    //2.用let和const声明的变量 存在暂时性死区

    //是否能修改声明的变量
    //1.用var和let声明的变量 可以重复修改
    //2.用const声明的变量 不可以修改
    // var aa = "1234";
    // aa = "123456";
    // let aa = "1234";
    // aa = "123456";
    // const aa = "1234";
    // aa = "123456"; //Assignment to constant variable.

    //使用const声明一个引用数据类型,只要不去修改内存地址,那么这个数据里面的内容是可以重复修改的
    // const obj = {
    //     a: 10
    // };
    // obj.a = 100
    // obj = { a:100 }

    // const 使用场景
    // const Pi = 3.1415926;
    // const API = "http://www.baidu.com";
    // const BaseUrl = "http://www.baidu.com";

    // let aa;
    // const aa; //Missing initializer in const declaration
    //使用const声明变量,必须赋值

    //变量提升:变量在声明之前可以使用,并且代码不报错 (预解释 预解析
    //1.用var声明的变量 存在变量提升
    //2.用let和const声明的变量 不存在变量提升
    //是否存在暂时性死区
    //在用let声明一个变量之前 都不能使用这个变量,否则就会报错, 在这之前的代码块,对于这个变量来说都叫暂时性死区
    //1.用var声明的变量 不存在暂时性死区
    //2.用let和const声明的变量 存在暂时性死区
    //是否允许重复声明变量
    //1.用var声明的变量 允许重复声明
    //2.用let和const声明的变量 不允许重复声明
    //是否存在块级作用域
    //作用域 全局作用域 局部作用域(函数作用域) 块级作用域
    //1.用var声明的变量 不存在块级作用域
    //2.用let和const声明的变量 存在块级作用域
    //是否能修改声明的变量
    //1.用var和let声明的变量 可以重复修改
    //2.用const声明的变量 不可以修改
    //使用const声明一个引用数据类型,只要不去修改内存地址,那么这个数据里面的内容是可以重复修改的

    //练习题
    //例子:1
    // let arr = [];
    // for (let i = 0; i < 2; i++) {
    //     //i ==> 0 1
    //     arr[i] = function () {
    //         console.log(i)
    //     }
    // }
    // arr[0]();//0
    // arr[1]();//1

    //例子:2
    var arr = [];
    //i ==> 0 1 2
    for (var i = 0; i < 2; i++) {
        arr[i] = function () {
            console.log(i)
        }
    }
    arr[0]();//2
    arr[1]();//2

    //作业: 不使用let  让上述例子2输出例子1的结果




</script>
</body>
</html>